﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.ComponentModel;
using System.Threading;
using System.Windows.Interop;
using System.Runtime.InteropServices;
using System.Windows;
using System.Net.Mail;

namespace Kiosk
{
    public static class sGlobals
    {
        #region timeout stuff
        [StructLayout(LayoutKind.Sequential)]
        struct LASTINPUTINFO
        {
            public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));
            [MarshalAs(UnmanagedType.U4)]
            public int cbSize;
            [MarshalAs(UnmanagedType.U4)]
            public UInt32 dwTime;
        }

        [DllImport("user32.dll")]
        static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

        static int GetLastInputTime()
        {
            int nIdleTime = 0;
            LASTINPUTINFO liiInfo = new LASTINPUTINFO();
            liiInfo.cbSize = Marshal.SizeOf(liiInfo);
            liiInfo.dwTime = 0;
            int nEnvTicks = Environment.TickCount;
            if (GetLastInputInfo(ref liiInfo))
            {
                int nLastInputTick = (int)liiInfo.dwTime;
                nIdleTime = nEnvTicks - nLastInputTick;
            }
            return ((nIdleTime > 0) ? (nIdleTime / 1000) : nIdleTime);
        }

        public static void idleTimer_Tick(object sender, EventArgs e)
        {
            //if the timer hits the autotimeout warning time then we display a message
            if (GetLastInputTime() > autoWarning && !hasLogout && !warningDisplayed && !sendingEmail)
            {
                warningDisplayed = true;
                AutoTimeoutWarning atw = new AutoTimeoutWarning();
                atw.ShowDialog();
                atw.Tag = "autoTimeoutWindow";
            }
            //if the timer hits the autotimeout logout time then we close the warning message and
            //automatically logout the user.
            else if (GetLastInputTime() > autoLogout && !hasLogout && warningDisplayed && !sendingEmail)
            {
                foreach (Window win in Application.Current.Windows)
                {
                    if ((string)win.Tag == "autoTimeoutWindow")
                    {
                        win.Close();
                    }
                }
                sGlobals.logout();
            }//end if
        }

        #endregion

        public static System.Windows.Forms.Timer idleTimer = new System.Windows.Forms.Timer();

        /// <summary>
        /// used for database interaction
        /// </summary>
        public static DBWrapper dbWrapper;
        
        public static KioskLogin kioskLogin;
        public static FocusedAreasOfStudy focusedAreasOfStudy;
        public static FavoriteMentors favoriteMentors;
        public static BrowseMentors browseMentors;
        public static ContactMentor contactMentor;
        public static Pathways pathways;
        public static FilterMentors filterMentors;
        public static MentorDisplay mentorDisplay;

        public static bool sendingEmail;
        public static SmtpClient smtpClient;
        public static string currentUsername;
        public static List<String> selectedAOSID; //area of study ID
        public static List<String> selectedPathwayID;
        public static string selectedMentorID;
        public static bool hasLogout;
        public static int autoWarning;
        public static int autoLogout;
        public static bool warningDisplayed;
        public static int loginActionId = -1;
        public static DateTime loginTime;

        private static LogoutScreen logoutScreen;
        public static BlankPage blank;


        /// <summary>
        /// reinstaniates all pages and variables, shows the login page
        /// </summary>
        public static void logout()
        {
            logoutScreen = new LogoutScreen();
            logoutScreen.Tag = "logoutScreen";
            logoutScreen.Show();

            foreach (Window win in Application.Current.Windows)  //housekeeping to clear out any possible other open windows
            {
                if (win.IsInitialized)
                {
                    if ((string)win.Tag == "logoutScreen" || (string)win.Tag == "blank")
                    {

                    }
                    else
                    {
                        win.Close();
                    }
                }
            }

            sendingEmail = false;
            currentUsername = null;
            warningDisplayed = false;
            loginActionId = -1;
            autoWarning = 0;
            autoLogout = 0;
            selectedAOSID = new List<String>(); //area of study ID
            selectedPathwayID = new List<String>();
            selectedMentorID = null;
            hasLogout = true;

            updateLog();
            dbWrapper = new DBWrapper();
            kioskLogin = new KioskLogin();
            focusedAreasOfStudy = new FocusedAreasOfStudy();
            favoriteMentors = new FavoriteMentors();
            browseMentors = new BrowseMentors();
            contactMentor = new ContactMentor();
            pathways = new Pathways();
            filterMentors = new FilterMentors();
            mentorDisplay = new MentorDisplay();            

            kioskLogin.Show();
            kioskLogin.Activate();

            logoutScreen.Close();
          
            kioskLogin.Show();           
        }

        public static void launchApplication()
        {

            sendingEmail = false;
            currentUsername = null;
            warningDisplayed = false;
            loginActionId = -1;
            autoWarning = 0;
            autoLogout = 0;
            selectedAOSID = new List<String>(); //area of study ID
            selectedPathwayID = new List<String>();
            selectedMentorID = null;
            hasLogout = true;

            dbWrapper = new DBWrapper();
            kioskLogin = new KioskLogin();
            focusedAreasOfStudy = new FocusedAreasOfStudy();
            favoriteMentors = new FavoriteMentors();
            browseMentors = new BrowseMentors();
            contactMentor = new ContactMentor();
            pathways = new Pathways();
            filterMentors = new FilterMentors();
            mentorDisplay = new MentorDisplay();
            blank = new BlankPage();
            blank.Tag = "blank";

            blank.Show();
            kioskLogin.Show();
            kioskLogin.Activate();
        }

        #region password stuff
        /// <summary>
        /// This method is used to validate the password of a user. 
        /// *****Note: This method does not prevent agains SQL injection*****
        /// </summary>
        /// <param name="username">The username of the user</param>
        /// <param name="password">The password of the user</param>
        /// <returns>A boolean wheter the password is valid or not</returns>
        public static Boolean isValidPassword(string username, string password)
        {
            string loginQuery = "SELECT users.password FROM users WHERE username = '" + username + "'";
            string hashedDBPassword =  dbWrapper.ExecuteScalarSQL(loginQuery); //get the DB password
            return HashData.IsValidPassword(username, password, hashedDBPassword);
        }//end method CheckPassword

        public static Boolean isValidPassword(string username, string password, ref char iRetVal)
        {
            string loginQuery = "SELECT users.password FROM users WHERE username = '" + username + "'";
            string permissionQuery = "SELECT permission FROM users WHERE username = '" + username + "'";
            string hashedDBPassword = dbWrapper.ExecuteScalarSQL(loginQuery); //get the DB password            
            string value = dbWrapper.ExecuteScalarSQL(permissionQuery);
            if (value != null && value != "")
                iRetVal = Convert.ToChar(value);
            return HashData.IsValidPassword(username, password, hashedDBPassword);
        }
        #endregion

        private static void updateLog()
        {
            if (loginActionId != -1)
            {
                TimeSpan ts = DateTime.Now - loginTime;
                int sessionTime = ((ts.Hours * 60) + ts.Minutes);
                string updateLogQuery = "UPDATE lgd_user_action SET session_time_minutes = " + sessionTime + " WHERE log_action_id = " + sGlobals.loginActionId;
                try
                {
                    dbWrapper.ExecuteNonQuery(updateLogQuery);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("There was an error connecting to the database with exception: {0}", ex.Message);
                }
            }
        }

        public static void createSmtpClient()
        {
            string usernameQuery = "SELECT setting_value FROM settings WHERE setting_name = 'USERNAME'";
            string serverQuery = "SELECT setting_value FROM settings WHERE setting_name = 'SERVER'";
            string passwordQuery = "SELECT setting_value FROM settings WHERE setting_name = 'PASSWORD'";
            string portQuery = "SELECT setting_value FROM settings WHERE setting_name = 'PORT'";
            string spaQuery = "SELECT setting_value FROM settings WHERE setting_name = 'REQUIRESSPA'";

            try
            {
                string username = sGlobals.dbWrapper.ExecuteScalarSQL(usernameQuery);
                string server = sGlobals.dbWrapper.ExecuteScalarSQL(serverQuery);
                string password = sGlobals.dbWrapper.ExecuteScalarSQL(passwordQuery);
                string port = sGlobals.dbWrapper.ExecuteScalarSQL(portQuery);
                bool reqSPA = Convert.ToBoolean(sGlobals.dbWrapper.ExecuteScalarSQL(spaQuery));

                //if the port is null then only user the server
                if (port == null || port == "")
                {
                    smtpClient = new SmtpClient(server);
                }
                else
                {
                    smtpClient = new SmtpClient(server, Convert.ToInt32(port));
                }

                if (reqSPA)
                {
                    smtpClient.EnableSsl = true;
                }
                smtpClient.UseDefaultCredentials = false;
                smtpClient.Credentials = new System.Net.NetworkCredential(username, password);
                smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
                smtpClient.Timeout = 60000;
            }
            catch (Exception ex)
            {
                if (!sGlobals.hasLogout)
                {
                    WarningMessage warning = new WarningMessage();
                    warning.lblMessage.Content = "There was a problem logging into the system.\r\nIf the problem persists, please contact your system administrator";
                    warning.ShowDialog();
                    logout();
                }
            }
        }
    }
}
